﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Threading;
using Path = System.IO.Path;

namespace SuperKit
{
    /// <summary>
    /// 将一个视频转化为安全的模式，原理是剪切视频的前3秒，使视频变成一个新的视频，这样的摆脱MD5的检查。
    /// 因为重新压制一次需要的代价太大了，处理大量的视频的时候出此“下策”。
    /// </summary>
    class SafelizeMovie : CommandExecutor {

        private class MovieFile {
            public FileInfo file { get; }
            public string Name => file.Name;
            public int Length { get; private set; }

            public MovieFile(FileInfo file) {
                this.file = file;
            }

            public void GainedLength() {
                Length = MixCombineMovie.GetMediaTimeLenSecond(file.FullName);
            }
        }

        public const string CUT_SECOND = "03";
        public const string START_MARK = "Duration: ";
        public const string END_MARK = ",";

        public SafelizeMovie(ArgReader arg, IExecutorOwner form, string fpath) : base(arg, form, fpath) {

        }

        public override void Execute() {
            Thread t = new Thread(OnProcess);
            t.Start();
        }

        private void OnProcess() {
            List<FileInfo> list = Kit.GetAllFiles(null, new DirectoryInfo(FilePath));

            foreach (var i in list) {
                Process(new MovieFile(i));
            }
            End();
        }

        private void Process(MovieFile item) {
            string outputPath = GetOutputPath(item.file.Name);

            string timeStr = GetMovieTime(item.file.FullName);
            Flush($"{item.Name}:{timeStr}");
            string cmd = $"-ss 00:00:{CUT_SECOND}.00 -to {timeStr}  -accurate_seek -i \"{item.file.FullName}\" -c copy  -avoid_negative_ts 1 \"{outputPath}\" -y";
            Process p = new Process();
            p.StartInfo.FileName = ConfigReader.Instance.FFMpegExe;
            p.StartInfo.Arguments = cmd;
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.CreateNoWindow = true;

            p.ErrorDataReceived += new System.Diagnostics.DataReceivedEventHandler((SenderObject, EventArgs) => {
                string message = EventArgs.Data;
                SetStatus(message);

            });

            p.Start();
            p.BeginErrorReadLine();
            p.WaitForExit();
            p.Close();
        }

        /// <summary>
        /// 获取视频的时间
        /// </summary>
        /// <param name="path"></param>
        /// <returns>一个字符串表示时间，例如00:01:02.23</returns>
        public static string GetMovieTime(string path) {
            Process p = new Process();
            p.StartInfo.FileName = ConfigReader.Instance.FFMpegExe;
            p.StartInfo.Arguments = $"-i \"{path}\"";
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.CreateNoWindow = true;

            string time = "0";

            p.ErrorDataReceived += new System.Diagnostics.DataReceivedEventHandler((SenderObject, EventArgs) => {
                string message = EventArgs.Data;
                if (message != null && message.Contains("Duration")) {
                    int start = message.IndexOf(START_MARK);
                    int end = message.IndexOf(END_MARK);
                    time = message.Substring(start + START_MARK.Length, end - start - START_MARK.Length);
                }

            });

            p.Start();
            p.BeginErrorReadLine();
            p.WaitForExit();
            p.Close();

            return time;
        }
    }
}
